package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.pojo.dto.FixDataJobDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.ReceiveStatusEnum;
import com.xbongbong.pro.enums.RefundStatusEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.script.pojo.dto.AllScriptDTO;
import com.xbongbong.pro.script.pojo.vo.ScriptVO;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.dao.ContractDao;
import com.xbongbong.saas.domain.dao.ContractProductDao;
import com.xbongbong.saas.domain.dao.InventoryDao;
import com.xbongbong.saas.domain.dao.TransferDao;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductionOrderProductEntity;
import com.xbongbong.saas.domain.entity.PurchaseProductEntity;
import com.xbongbong.saas.domain.entity.ReturnedPurchaseProductEntity;
import com.xbongbong.saas.domain.entity.TransferProductEntity;
import com.xbongbong.saas.domain.entity.WorkOrderProductEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.InventoryEntityExt;
import com.xbongbong.saas.domain.entity.ext.PurchaseEntityExt;
import com.xbongbong.saas.domain.entity.ext.RefundEntityExt;
import com.xbongbong.saas.domain.entity.ext.ReturnedPurchaseEntityExt;
import com.xbongbong.saas.domain.entity.ext.TransferEntityExt;
import com.xbongbong.saas.enums.InstockTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.business.TransferEnum;
import com.xbongbong.saas.enums.dictionary.AllInBoundEnum;
import com.xbongbong.saas.enums.dictionary.AllOutBoundEnum;
import com.xbongbong.saas.enums.dictionary.InventoryNewStatusEnum;
import com.xbongbong.saas.enums.dictionary.ReturnedStatusEnum;
import com.xbongbong.saas.enums.dictionary.ShipStatusEnum;
import com.xbongbong.saas.enums.dictionary.TransferNewStatusEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.InstockProductModel;
import com.xbongbong.saas.model.InventoryModel;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.ProductionOrderProductModel;
import com.xbongbong.saas.model.PurchaseModel;
import com.xbongbong.saas.model.PurchaseProductModel;
import com.xbongbong.saas.model.RefundModel;
import com.xbongbong.saas.model.ReturnedPurchaseModel;
import com.xbongbong.saas.model.ReturnedPurchaseProductModel;
import com.xbongbong.saas.model.TransferModel;
import com.xbongbong.saas.model.TransferProductModel;
import com.xbongbong.saas.model.WorkOrderProductModel;
import com.xbongbong.saas.service.RepairExplainService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.model.CompanyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;

/**
 * @author jiyonghui
 * @className FieldImproveController
 * @description
 * @date 2020/5/8   9:28
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/script/field/improve")
public class FieldImproveController {
    private static final Logger LOG = LoggerFactory.getLogger(FieldImproveController.class);

    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private PurchaseModel purchaseModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private ReturnedPurchaseModel returnedPurchaseModel;
    @Resource
    private InstockProductModel instockProductModel;
    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private RepairExplainService repairExplainService;
    @Resource
    private TransferModel transferModel;
    @Resource
    private RefundModel refundModel;
    @Resource
    private InventoryModel inventoryModel;
    @Resource
    private WorkOrderProductModel workOrderProductModel;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private PurchaseProductModel purchaseProductModel;
    @Resource
    private ReturnedPurchaseProductModel returnedPurchaseProductModel;
    @Resource
    private ProductionOrderProductModel productionOrderProductModel;
    @Resource
    private TransferProductModel transferProductModel;
    @Resource
    private InventoryDao inventoryDao;
    @Resource
    private TransferDao transferDao;
    @Resource
    private ContractProductDao contractProductDao;
    @Resource
    private ContractDao contractDao;


    /**
     * 增加关联产品字段
     * 写死的仅用于单据优化上线
     * @param allScriptDTO
     * @param br
     * @return
     * @throws XbbException
     */
    @RequestMapping(value = "/secondInitAddAllProduct", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String initAddAllProduct(@RequestBody @Valid AllScriptDTO allScriptDTO, BindingResult br) throws XbbException {
        if (!proBaseConfig.getXbbCode().equals(allScriptDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        XbbResponse<ScriptVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ScriptVO scriptVO = repairExplainService.repairAddExplainProduct(allScriptDTO);
                response = new XbbResponse<>(scriptVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }



    /**
     * 增加关联产品字段
     * 写死的仅用于单据优化上线
     * @param allScriptDTO
     * @param br
     * @return
     * @throws XbbException
     */
    @RequestMapping(value = "/firstInitAddAllProduct", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String initAddAllProduct2(@RequestBody @Valid AllScriptDTO allScriptDTO, BindingResult br) throws XbbException {
        if (!proBaseConfig.getXbbCode().equals(allScriptDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        XbbResponse<ScriptVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ScriptVO scriptVO = repairExplainService.repairAddExplainProduct2(allScriptDTO);
                response = new XbbResponse<>(scriptVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 刷老数据合同退货数量
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixContractInStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixContractInStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = refundModel.getCorpids();
        }
        int index = 1;
        long start = DateTimeUtil.getInt();
        Map<String,Double> oldDataUpdateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Long> contractIdList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (String corpid : corpidList) {
            LOG.warn("fixContractInStockNum:" + index + "/" + corpidList.size());
            index++;
            long idGte = 0L;
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("type", XbbRefTypeEnum.REFUND.getCode());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                List<RefundEntityExt> refundEntityExtList = refundModel.findEntitys(param);
                if (refundEntityExtList.isEmpty()){
                    break;
                }
                idGte = refundEntityExtList.get(refundEntityExtList.size()-1).getId();
                List<Long> refundIdList = new ArrayList<>();
                Map<Long,Long> idMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                refundEntityExtList.forEach(item ->{
                    refundIdList.add(item.getData().getLong(RefundEnum.RED_CONTRACT_ID.getAttr()));
                    contractIdList.add(item.getData().getLong(RefundEnum.CONTRACT_ID.getAttr()));
                    idMap.put(item.getData().getLong(RefundEnum.RED_CONTRACT_ID.getAttr()),item.getData().getLong(RefundEnum.CONTRACT_ID.getAttr()));
                });
                param.clear();
                param.put(StringConstant.CORPID,corpid);
                param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                param.put("contractIdIn",refundIdList);
                List<ContractProductEntity> contractProductEntityList = contractProductModel.findEntitys(param);
                List<Long> refundRefProductIdList = new ArrayList<>();
                for (ContractProductEntity entity : contractProductEntityList) {
                    if (!Objects.isNull(entity.getRefProductId())) {
                        //新数据要维护的话等我的字段上线
                        refundRefProductIdList.add(entity.getRefProductId());
                        continue;
                    }
                    String key = idMap.get(entity.getContractId()) + "_" + entity.getProductId();
                    Double stock = oldDataUpdateMap.getOrDefault(key,0D);
                    //存的是负数
                    stock = Arith.add(stock,-entity.getProductNum());
                    oldDataUpdateMap.put(key,stock);
                }
                if (!refundRefProductIdList.isEmpty()) {
                    param.clear();
                    param.put(StringConstant.CORPID,corpid);
                    param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                    param.put("idIn", refundRefProductIdList);
                    List<OutstockProductEntity> outstockProductEntityList = outstockProductModel.findEntitys(param);
                    for (OutstockProductEntity entity : outstockProductEntityList) {
                        if (Objects.isNull(entity.getRefProductId())) {
                            String key = entity.getRefId() + "_" + entity.getProductId();
                            Double stock = oldDataUpdateMap.getOrDefault(key,0D);
                            //存的是负数
                            stock = Arith.add(stock,entity.getProductNum());
                            oldDataUpdateMap.put(key,stock);
                        }
                    }
                }
            }
            if (!contractIdList.isEmpty()) {
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID,corpid);
                param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                param.put("contractIdIn",contractIdList);
                param.put("type",XbbRefTypeEnum.CONTRACT.getCode());
                List<ContractProductEntity> contractProductEntityList = contractProductModel.findEntitys(param);
                List<ContractProductEntity> updateList = new ArrayList<>();
                for (ContractProductEntity entity : contractProductEntityList) {
                    String key = entity.getContractId() + "_" + entity.getProductId();
                    if (oldDataUpdateMap.containsKey(key)){
                        Double outNum = oldDataUpdateMap.get(key);
                        if (Double.compare(outNum,entity.getProductNum()) > 0) {
                            entity.setInstockNum(entity.getProductNum());
                            oldDataUpdateMap.put(key,Arith.sub(outNum,entity.getProductNum()));
                            updateList.add(entity);
                        } else {
                            entity.setInstockNum(outNum);
                            oldDataUpdateMap.remove(key);
                            updateList.add(entity);
                        }
                    }
                }
                if (!updateList.isEmpty()) {
                    contractProductModel.updateInStockForJob(updateList,corpid);
                }
            }
        }
        LOG.warn("fixContractInStockNum over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }

    /**
     * 刷合同出货数量
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixContractOutStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixContractOutStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = contractProductDao.getCorpidList();
        }
        int index = 1;
        long start = DateTimeUtil.getInt();
        for (String corpid : corpidList) {
            LOG.warn("fixContractOutStockNum:" + index + "/" + corpidList.size());
            index++;
            long idGte = 0L;
            HashSet<Long> allContractIds = new HashSet<>();
            Map<Object,Double> productMap = new HashMap<>();
            HashSet<Long> newContractIds = new HashSet<>();
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                param.put("type", OutstockTypeEnum.CONTRACT_OUTSTOCK.getCode());
                List<OutstockProductEntity> entitys = outstockProductModel.findEntitys(param);
                if (entitys.isEmpty()){
                    break;
                }
                idGte = entitys.get(entitys.size()-1).getId();

                for (OutstockProductEntity entity : entitys) {
                    Long refId = entity.getRefId();
                    allContractIds.add(refId);
                    Long refProductId = entity.getRefProductId();
                    if (Objects.nonNull(refProductId)){
                        String key = refId + "_" + refProductId;
                        newContractIds.add(refId);
                        Double num = productMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        productMap.put(key,num);
                    }else {
                        Long productId = entity.getProductId();
                        String key = refId + "_" + productId;
                        Double num = productMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        productMap.put(key,num);
                    }
                }
            }
            if (allContractIds.isEmpty()) {
                continue;
            }
            Map<String,Object> param = new HashMap<>();
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("contractIdIn",allContractIds);
            List<ContractProductEntity> contractProductEntitys = contractProductModel.findEntitys(param);


            List<ContractProductEntity> contractProductEntities = new ArrayList<>(1000);

            for (ContractProductEntity contractProductEntity : contractProductEntitys) {

                Long contractId = contractProductEntity.getContractId();
                if (newContractIds.contains(contractId)) {
                    //新数据逻辑
                    String key = contractId + "_" + contractProductEntity.getId();
                    if (!productMap.containsKey(key)) {
                        contractProductEntity.setOutstockNum(0D);
                        contractProductEntity.setContractOutstockNum(0D);
                    }else {
                        contractProductEntity.setOutstockNum(productMap.get(key));
                        contractProductEntity.setContractOutstockNum(productMap.get(key));
                        productMap.remove(key);
                    }
                    contractProductEntities.add(contractProductEntity);
                    if (contractProductEntities.size() >= 1000) {
                        contractProductDao.updateOutStockForJob(contractProductEntities,corpid);
                        contractProductEntities = new ArrayList<>(1000);
                    }
                    continue;
                }
                Long productId = contractProductEntity.getProductId();

                String key = contractId + "_" + productId;
                if (productMap.isEmpty() || !productMap.containsKey(key)) {
                    contractProductEntity.setOutstockNum(0D);
                    contractProductEntity.setContractOutstockNum(0D);
                    contractProductEntities.add(contractProductEntity);
                    if (contractProductEntities.size() >= 1000) {
                        contractProductDao.updateOutStockForJob(contractProductEntities,corpid);
                        contractProductEntities = new ArrayList<>(1000);
                    }
                    continue;
                }
                Double productNum = contractProductEntity.getProductNum();
                Double num = productMap.get(key);

                Double outstockNum ;
                if (productNum - num >= 0) {
                    outstockNum = num;
                    productMap.remove(key);
                }else {
                    outstockNum = productNum;
                    productMap.put(key,Arith.sub(num,outstockNum));
                }

                contractProductEntity.setOutstockNum(outstockNum);
                contractProductEntity.setContractOutstockNum(outstockNum);
                contractProductEntities.add(contractProductEntity);
                if (contractProductEntities.size() >= 1000) {
                    contractProductDao.updateOutStockForJob(contractProductEntities,corpid);
                    contractProductEntities = new ArrayList<>(1000);
                }
            }
            if (!contractProductEntities.isEmpty()) {
                contractProductDao.updateOutStockForJob(contractProductEntities,corpid);
            }
        }
        LOG.warn("fixContractOutStockNum over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }



    /**
     * 刷退货退款入货数量
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixRefundInStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixRefundInStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = refundModel.getCorpids();
        }
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fixRefundInStockNum:" + index + "/" + corpidList.size());
            index++;
            long idGte = 0L;
            HashSet<Long> allrefundIds = new HashSet<>();
            Map<Object,Double> instockPorductMap = new HashMap<>();
            HashSet<Long> newRefundIds = new HashSet<>();
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                param.put("type",  InstockTypeEnum.RED_CONTRACT_INSTOCK.getCode());
                List<InstockProductEntity> entitys = instockProductModel.findEntitys(param);
                if (entitys.isEmpty()){
                    break;
                }
                idGte = entitys.get(entitys.size()-1).getId();

                for (InstockProductEntity entity : entitys) {
                    Long refId = entity.getRefId();
                    Long refProductId = entity.getRefProductId();
                    allrefundIds.add(refId);
                    if (Objects.nonNull(refProductId)) {
                        newRefundIds.add(refId);
                        Long key = refProductId;
                        Double num = instockPorductMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        instockPorductMap.put(key,num);
                    }else {
                        String key = refId + "_" + entity.getProductId();
                        Double num = instockPorductMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        instockPorductMap.put(key,num);
                    }
                }
            }
            if (allrefundIds.isEmpty()) {
                continue;
            }

            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("idIn",allrefundIds);
            List<RefundEntityExt> entitys = refundModel.findEntitys(param);
            HashSet<Long> allcontractIds = new HashSet<>();
            HashMap<Long, Long> refundAndRedContractIds = new HashMap();
            for (RefundEntityExt entity : entitys) {
                allcontractIds.add(entity.getData().getLong(RefundEnum.RED_CONTRACT_ID.getAttr()));
                refundAndRedContractIds.put(entity.getData().getLong(RefundEnum.RED_CONTRACT_ID.getAttr()),entity.getId());
            }

            param.clear();
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("contractIdIn",allcontractIds);
            List<ContractProductEntity> entitys2 = contractProductModel.findEntitys(param);

            List<ContractProductEntity> contractProductEntities = new ArrayList<>(1000);

            for (ContractProductEntity entity : entitys2) {

                Long contractId = entity.getContractId();
                if (Objects.nonNull(entity.getRefProductId())) {
                    Long key = entity.getId();
                    if (!instockPorductMap.containsKey(key)) {
                        entity.setInstockNum(0D);
                    }else {
                        Double num = instockPorductMap.get(key);
                        entity.setInstockNum(num);
                        instockPorductMap.remove(key);
                    }
                    contractProductEntities.add(entity);
                    if (contractProductEntities.size() >= 1000) {
                        contractProductDao.updateBatch(contractProductEntities,corpid);
                        contractProductEntities = new ArrayList<>(1000);
                    }
                    continue;
                }
                Long productId = entity.getProductId();
                Long refId = refundAndRedContractIds.get(contractId);
                String key = refId + "_" + productId;
                if (instockPorductMap.isEmpty() || !instockPorductMap.containsKey(key)) {
                    entity.setInstockNum(0D);
                    contractProductEntities.add(entity);
                    if (contractProductEntities.size() >= 1000) {
                        contractProductDao.updateBatch(contractProductEntities,corpid);
                        contractProductEntities = new ArrayList<>(1000);
                    }
                    continue;
                }
                Double productNum = Math.abs(entity.getProductNum());
                Double num = instockPorductMap.get(key);

                Double instockNum;
                if (productNum - num >= 0) {
                    instockNum = num;
                    instockPorductMap.remove(key);
                }else {
                    instockNum = productNum;
                    instockPorductMap.put(key,Arith.sub(num,instockNum));
                }
                entity.setInstockNum(instockNum);
                contractProductEntities.add(entity);
                if (contractProductEntities.size() >= 1000) {
                    contractProductDao.updateBatch(contractProductEntities,corpid);
                    contractProductEntities = new ArrayList<>(1000);
                }
            }
            if (!contractProductEntities.isEmpty()) {
                contractProductDao.updateBatch(contractProductEntities,corpid);
            }
        }
        LOG.warn("fixRefundInStockNum over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }



    /**
     * 刷采购退货单出货数量
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixReturnPurchaseOutStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixReturnPurchaseOutStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = returnedPurchaseModel.getCorpids();
        }
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fixReturnPurchaseOutStockNum:" + index + "/" + corpidList.size());
            index++;
            long idGte = 0L;
            HashSet<Long> allReturnPurchaseIds = new HashSet<>();
            Map<Object,Double> productMap = new HashMap<>();
            HashSet<Long> newReturnPurchaseIds = new HashSet<>();
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                param.put("type",  OutstockTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode());
                List<OutstockProductEntity> entitys = outstockProductModel.findEntitys(param);
                if (entitys.isEmpty()){
                    break;
                }
                idGte = entitys.get(entitys.size()-1).getId();
                for (OutstockProductEntity entity : entitys) {
                    Long refId = entity.getRefId();
                    allReturnPurchaseIds.add(refId);
                    Long refProductId = entity.getRefProductId();
                    if (Objects.nonNull(refProductId)) {
                        String key = refId + "_" + refProductId;
                        newReturnPurchaseIds.add(refId);
                        Double num = productMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        productMap.put(key,num);
                    }else {
                        Long productId = entity.getProductId();
                        String key = refId + "_" + productId;
                        Double num = productMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        productMap.put(key,num);
                    }
                }
            }
            if (allReturnPurchaseIds.isEmpty()) {
                continue;
            }
            Map<String,Object> param = new HashMap<>();
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("returnPurchaseIdIn",allReturnPurchaseIds);
            List<ReturnedPurchaseProductEntity> returnedPurchaseProductEntities = returnedPurchaseProductModel.findEntitys(param);


            List<ReturnedPurchaseProductEntity> updateReturnedPurchaseProducts  = new ArrayList<>(1000);

            for (ReturnedPurchaseProductEntity returnedPurchaseProductEntity : returnedPurchaseProductEntities) {

                Long returnPurchaseId = returnedPurchaseProductEntity.getReturnPurchaseId();
                if (newReturnPurchaseIds.contains(returnPurchaseId)) {
                    //新数据逻辑
                    String key = returnPurchaseId + "_" + returnedPurchaseProductEntity.getId();
                    if (!productMap.containsKey(key)) {
                        returnedPurchaseProductEntity.setOutstockNum(0D);
                    }else {
                        returnedPurchaseProductEntity.setOutstockNum(productMap.get(key));
                        productMap.remove(key);
                    }
                    updateReturnedPurchaseProducts.add(returnedPurchaseProductEntity);
                    if (updateReturnedPurchaseProducts.size() >= 1000) {
                        returnedPurchaseProductModel.updateBatch(updateReturnedPurchaseProducts,corpid);
                        updateReturnedPurchaseProducts = new ArrayList<>(1000);
                    }
                    continue;
                }
                Long productId = returnedPurchaseProductEntity.getProductId();

                String key = returnPurchaseId + "_" + productId;
                if (productMap.isEmpty() || !productMap.containsKey(key)) {
                    returnedPurchaseProductEntity.setOutstockNum(0D);
                    updateReturnedPurchaseProducts.add(returnedPurchaseProductEntity);
                    if (updateReturnedPurchaseProducts.size() >= 1000) {
                        returnedPurchaseProductModel.updateBatch(updateReturnedPurchaseProducts,corpid);
                        updateReturnedPurchaseProducts = new ArrayList<>(1000);
                    }
                    continue;
                }
                Double productNum = returnedPurchaseProductEntity.getProductNum();
                Double num = productMap.get(key);

                Double outstockNum ;
                if (productNum - num >= 0) {
                    outstockNum = num;
                    productMap.remove(key);
                }else {
                    outstockNum = productNum;
                    productMap.put(key,Arith.sub(num,outstockNum));
                }

                returnedPurchaseProductEntity.setOutstockNum(outstockNum);
                updateReturnedPurchaseProducts.add(returnedPurchaseProductEntity);
                if (updateReturnedPurchaseProducts.size() >= 1000) {
                    returnedPurchaseProductModel.updateBatch(updateReturnedPurchaseProducts,corpid);
                    updateReturnedPurchaseProducts = new ArrayList<>(1000);
                }
            }
            if (!updateReturnedPurchaseProducts.isEmpty()) {
                returnedPurchaseProductModel.updateBatch(updateReturnedPurchaseProducts,corpid);
            }
        }
        LOG.warn("fixReturnPurchaseOutStockNum over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }



    /**
     * 刷数据采购合同入库数量
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixPurchaseInStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPurchaseInStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = purchaseModel.getCorpidList();
        }
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fixPurchaseInStockNum:" + index + "/" + corpidList.size());
            index++;
            long idGte = 0L;
            HashSet<Long> allpurchaseIds = new HashSet<>();
            Map<Object,Double> instockPorductMap = new HashMap<>();
            HashSet<Long> newPurchaseIds = new HashSet<>();
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                param.put("type",  InstockTypeEnum.PURCHASE_INSTOCK.getCode());
                List<InstockProductEntity> entitys = instockProductModel.findEntitys(param);
                if (entitys.isEmpty()){
                    break;
                }
                idGte = entitys.get(entitys.size()-1).getId();
                for (InstockProductEntity entity : entitys) {
                    Long refProductId = entity.getRefProductId();
                    Long refId = entity.getRefId();
                    allpurchaseIds.add(refId);
                    if (Objects.nonNull(refProductId)) {
                        newPurchaseIds.add(refId);
                        String key = refId + "_" + refProductId;
                        Double num = instockPorductMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        instockPorductMap.put(key,num);
                    }else {
                        String key = refId + "_" + entity.getProductId();
                        Double num = instockPorductMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        instockPorductMap.put(key,num);
                    }
                }
            }
            if (allpurchaseIds.isEmpty()) {
                continue;
            }
            Map<String,Object> param = new HashMap<>();
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("purchaseIdIn",allpurchaseIds);
            List<PurchaseProductEntity> entitys = purchaseProductModel.findEntitys(param);
            List<PurchaseProductEntity> purchaseProductEntities = new ArrayList<>(1000);

            for (PurchaseProductEntity entity : entitys) {

                Long contractId = entity.getPurchaseSheetId();
                if (newPurchaseIds.contains(contractId)) {
                    String key = contractId + "_" + entity.getId();
                    if (!instockPorductMap.containsKey(key)) {
                        entity.setInstockNum(0D);
                    }else {
                        Double num = instockPorductMap.get(key);
                        entity.setInstockNum(num);
                        instockPorductMap.remove(key);
                    }
                    purchaseProductEntities.add(entity);
                    if (purchaseProductEntities.size() >= 1000) {
                        purchaseProductModel.updateBatch(purchaseProductEntities,corpid);
                        purchaseProductEntities = new ArrayList<>(1000);
                    }
                    continue;
                }
                Long productId = entity.getProductId();

                String key = contractId + "_" + productId;
                if (instockPorductMap.isEmpty() || !instockPorductMap.containsKey(key)) {
                    entity.setInstockNum(0D);
                    purchaseProductEntities.add(entity);
                    if (purchaseProductEntities.size() >= 1000) {
                        purchaseProductModel.updateBatch(purchaseProductEntities,corpid);
                        purchaseProductEntities = new ArrayList<>(1000);
                    }
                    continue;
                }
                Double productNum = entity.getProductNum();
                Double num = instockPorductMap.get(key);

                Double instockNum;
                if (productNum - num >= 0) {
                    instockNum = num;
                    instockPorductMap.remove(key);
                }else {
                    instockNum = productNum;
                    instockPorductMap.put(key,Arith.sub(num,instockNum));
                }
                entity.setInstockNum(instockNum);
                purchaseProductEntities.add(entity);
                if (purchaseProductEntities.size() >= 1000) {
                    purchaseProductModel.updateBatch(purchaseProductEntities,corpid);
                    purchaseProductEntities = new ArrayList<>(1000);
                }
            }
            if (!purchaseProductEntities.isEmpty()) {
                purchaseProductModel.updateBatch(purchaseProductEntities,corpid);
            }
        }
        LOG.warn("fixPurchaseInStockNum over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }



    /**
     * 刷采购合同退货数量
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixPurchaseOutStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPurchaseOutStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        List<String> corpidList = returnedPurchaseModel.getCorpids();
        int index = 1;
        long start = DateTimeUtil.getInt();
        for (String corpid : corpidList) {
            LOG.warn(corpid + ":" + index + "/" + corpidList.size());
            index++;
            Long idGte = 0L;
            Map<String,Double> oldDataUpdateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Set<Long> purchaseIdList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            while (true) {
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID,corpid);
                param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                param.put("idGte",idGte);
                param.put("orderByStr","id asc");
                param.put("pageSize",1000);
                List<ReturnedPurchaseEntityExt> returnedPurchaseEntityExtList = returnedPurchaseModel.findEntitys(param);
                if (returnedPurchaseEntityExtList.isEmpty()){
                    break;
                }
                idGte = returnedPurchaseEntityExtList.get(returnedPurchaseEntityExtList.size()-1).getId();
                List<Long> returnedPurchaseIdList = new ArrayList<>();
                Map<Long,Long> idMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                returnedPurchaseEntityExtList.forEach(item -> {
                    returnedPurchaseIdList.add(item.getId());
                    purchaseIdList.add(item.getData().getLong(ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr()));
                    idMap.put(item.getId(),item.getData().getLong(ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr()));
                });
                param.clear();
                param.put(StringConstant.CORPID,corpid);
                param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                param.put("returnPurchaseIdIn",returnedPurchaseIdList);
                List<ReturnedPurchaseProductEntity> returnedPurchaseProductEntityList = returnedPurchaseProductModel.findEntitys(param);
                List<Long> refundRefProductIdList = new ArrayList<>();
                for (ReturnedPurchaseProductEntity entity : returnedPurchaseProductEntityList) {
                    if (!Objects.isNull(entity.getRefProductId())) {
                        //新数据要维护的话等我的字段上线
                        refundRefProductIdList.add(entity.getRefProductId());
                        continue;
                    }
                    String key = idMap.get(entity.getReturnPurchaseId()) + "_" + entity.getProductId();
                    Double stock = oldDataUpdateMap.getOrDefault(key,0D);
                    stock = Arith.add(stock,entity.getProductNum());
                    oldDataUpdateMap.put(key,stock);
                }
                if (!refundRefProductIdList.isEmpty()) {
                    param.clear();
                    param.put(StringConstant.CORPID,corpid);
                    param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                    param.put("idIn", refundRefProductIdList);
                    List<InstockProductEntity> instockProductEntityList = instockProductModel.findEntitys(param);
                    for (InstockProductEntity entity : instockProductEntityList) {
                        if (Objects.isNull(entity.getRefProductId())) {
                            String key = entity.getRefId() + "_" + entity.getProductId();
                            Double stock = oldDataUpdateMap.getOrDefault(key,0D);
                            //存的是负数
                            stock = Arith.add(stock,entity.getProductNum());
                            oldDataUpdateMap.put(key,stock);
                        }
                    }
                }
            }
            if (!purchaseIdList.isEmpty()){
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID,corpid);
                param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                param.put("purchaseIdIn",purchaseIdList);
                List<PurchaseProductEntity> purchaseProductEntityList = purchaseProductModel.findEntitys(param);
                List<PurchaseProductEntity> updateList = new ArrayList<>();
                for (PurchaseProductEntity entity : purchaseProductEntityList){
                    String key = entity.getPurchaseSheetId() + "_" + entity.getProductId();
                    if (oldDataUpdateMap.containsKey(key)){
                        Double outNum = oldDataUpdateMap.get(key);
                        if (Double.compare(outNum,entity.getProductNum()) > 0) {
                            entity.setOutstockNum(entity.getProductNum());
                            oldDataUpdateMap.put(key,Arith.sub(outNum,entity.getProductNum()));
                            updateList.add(entity);
                        } else {
                            entity.setOutstockNum(outNum);
                            oldDataUpdateMap.remove(key);
                            updateList.add(entity);
                        }
                    }
                }
                if (!updateList.isEmpty()) {
                    purchaseProductModel.updateOutStockForJob(updateList,corpid);
                }
            }

        }
        LOG.warn("comsume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("fixPurchaseOutStockNum over");
        return null;
    }



    /**
     * 刷工单出货数量
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixWorkOrderOutStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixWorkOrderOutStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = workOrderProductModel.getCorpidList();
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fixWorkOrderOutStockNum:" + index + "/" + corpidList.size() + "/" + corpid);
            index++;
            long idGte = 0L;
            HashSet<Long> allWorkOrderIds = new HashSet<>();
            Map<Long,Double> outstockPorductMap = new HashMap<>();
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                param.put("type",  OutstockTypeEnum.WORK_ORDER_OUTSTOCK.getCode());
                List<OutstockProductEntity> entitys = outstockProductModel.findEntitys(param);
                if (entitys.isEmpty()){
                    break;
                }
                idGte = entitys.get(entitys.size()-1).getId();
                for (OutstockProductEntity entity : entitys) {
                    allWorkOrderIds.add(entity.getRefId());
                    Long refProductId = entity.getRefProductId();
                    if (Objects.nonNull(refProductId)) {
                        Double num = outstockPorductMap.getOrDefault(refProductId, 0D);
                        num += entity.getProductNum();
                        outstockPorductMap.put(refProductId, num);
                    }
                }
            }
            if (allWorkOrderIds.isEmpty()) {
                continue;
            }
            Map<String,Object> param = new HashMap<>();
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("idIn",outstockPorductMap.keySet());
            List<WorkOrderProductEntity> entitys = workOrderProductModel.findEntitys(param);
            List<WorkOrderProductEntity> updateEntitys = new ArrayList<>(1000);
            for (WorkOrderProductEntity entity : entitys) {
                entity.setOutstockNum(outstockPorductMap.getOrDefault(entity.getId(), 0D));
                updateEntitys.add(entity);
                if (updateEntitys.size() >= 1000) {
                    workOrderProductModel.updateBatch(updateEntitys,corpid);
                    updateEntitys = new ArrayList<>(1000);
                }
            }
            if (!updateEntitys.isEmpty()) {
                workOrderProductModel.updateBatch(updateEntitys,corpid);
            }


        }
        LOG.warn("fixWorkOrderOutStockNum over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }

    /**
     * 刷生产单领料数量
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixProductionOutStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixProductionOutStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = productionOrderProductModel.getCorpids();
        }
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fixProductionOutStockNum:" + index + "/" + corpidList.size());
            index++;
            long idGte = 0L;
            HashSet<Long> allProductionOrderIds = new HashSet<>();

            Map<Object,Double> outstockPorductMap = new HashMap<>();
            List<Long> newProductionIds = new ArrayList<>();
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                param.put("type",  OutstockTypeEnum.MATERIEL_OUTSTOCK.getCode());
                List<OutstockProductEntity> entitys = outstockProductModel.findEntitys(param);
                if (entitys.isEmpty()){
                    break;
                }
                idGte = entitys.get(entitys.size()-1).getId();
                for (OutstockProductEntity entity : entitys) {
                    Long refId = entity.getRefId();
                    allProductionOrderIds.add(refId);
                    Long refProductId = entity.getRefProductId();
                    if (Objects.nonNull(refProductId)) {
                        String key = refId + "_" + refProductId;
                        newProductionIds.add(refId);
                        Double num = outstockPorductMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        outstockPorductMap.put(key,num);
                    }else {
                        String key = refId + "_" + entity.getProductId();
                        Double num = outstockPorductMap.getOrDefault(key,0D);
                        num = Arith.add(entity.getProductNum(),num) ;
                        outstockPorductMap.put(key,num);
                    }
                }
            }
            if (allProductionOrderIds.isEmpty()) {
                continue;
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("proOrderIdIn",allProductionOrderIds);
            param.put("type",2);
            List<ProductionOrderProductEntity> entitys = productionOrderProductModel.findEntitys(param);
            List<ProductionOrderProductEntity> updateEntitys = new ArrayList<>(1000);
            for (ProductionOrderProductEntity entity : entitys) {
                Long contractId = entity.getProductionOrderId();
                if (newProductionIds.contains(contractId)) {
                    //新数据逻辑
                    String key = contractId + "_" + entity.getId();
                    if (!outstockPorductMap.containsKey(key)) {
                        entity.setOutstockNum(0D);
                    }else {
                        entity.setOutstockNum(outstockPorductMap.get(key));
                        outstockPorductMap.remove(key);
                    }
                    updateEntitys.add(entity);
                    if (updateEntitys.size() >= 1000) {
                        productionOrderProductModel.updateBatch(updateEntitys, corpid);
                        updateEntitys = new ArrayList<>(1000);
                    }
                    continue;
                }
                Long productId = entity.getProductId();


                String key = contractId + "_" + productId;
                if (outstockPorductMap.isEmpty() || !outstockPorductMap.containsKey(key)) {
                    entity.setOutstockNum(0D);
                    updateEntitys.add(entity);
                    if (updateEntitys.size() >= 1000) {
                        productionOrderProductModel.updateBatch(updateEntitys, corpid);
                        updateEntitys = new ArrayList<>(1000);
                    }
                    continue;
                }
                Double productNum = entity.getProductNum();
                Double num = outstockPorductMap.get(key);

                Double outstockNum;
                if (productNum - num >= 0) {
                    outstockNum = num;
                    outstockPorductMap.remove(key);
                }else {
                    outstockNum = productNum;
                    outstockPorductMap.put(key,Arith.sub(num,outstockNum));
                }

                entity.setOutstockNum(outstockNum);
                updateEntitys.add(entity);
                if (updateEntitys.size() >= 1000) {
                    productionOrderProductModel.updateBatch(updateEntitys, corpid);
                    updateEntitys = new ArrayList<>(1000);
                }
            }
            if (!updateEntitys.isEmpty()) {
                productionOrderProductModel.updateBatch(updateEntitys,corpid);
            }

        }
        LOG.warn("fixProductionOutStockNum over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }

//    /**
//     * 刷调拨单领料数量
//     * @param fixDataJobDTO
//     * @param br
//     * @return
//     * @throws Exception
//     */
//
//    @RequestMapping(value = "/fixTransferOutStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
//    public String fixTransferOutStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
//        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
//            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
//        }
//        List<String> corpidList = transferModel.getCorpids();
//        int index = 1;
//
//        for (String corpid : corpidList) {
//            LOG.warn("fixTransferOutStockNum:" + index + "/" + corpidList.size());
//            index++;
//            Long dataDataMark = 0L;
//            List<PaasFormDataEntityExt> paasFormDataEntityExtList = new ArrayList<>();
//            paasFormDataEntityExtList.add(new PaasFormDataEntityExt());
//            HashSet<Long> allTransferIds = new HashSet<>();
//            List<Long> allOutstockIds = new ArrayList<>();
//            Map<Long,Long> transferAndOutstock = new HashMap<>();
//            while (!paasFormDataEntityExtList.isEmpty()) {
//                BoolQueryBuilder boolQueryBuilder = boolQuery();
//                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
//                boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
//                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE), OutstockTypeEnum.TRANSFER_OUTSTOCK.getCode()));
//                ListVO listVO = scriptEsHelper.list(boolQueryBuilder, 1000, PaasFormDataEntityExt.class, IndexTypeEnum.IDX_SAAS_OUTSTOCK, dataDataMark,Arrays.asList("id",FieldTypeEnum.DATAID.getAlias(),OutstockEnum.getAttrConnectData(OutstockEnum.REF_ID)));
//                paasFormDataEntityExtList = listVO.getList();
//                dataDataMark = listVO.getDataIdMark();
//                if (paasFormDataEntityExtList.isEmpty()) {
//                    continue;
//                }
//                for (PaasFormDataEntityExt transferEntity : paasFormDataEntityExtList) {
//                    allTransferIds.add(transferEntity.getData().getLong(OutstockEnum.REF_ID.getAttr()));
//                    allOutstockIds.add(transferEntity.getDataId());
//                    transferAndOutstock.put(transferEntity.getDataId(),transferEntity.getData().getLong(OutstockEnum.REF_ID.getAttr()));
//                }
//            }
//            if (allTransferIds.isEmpty()) {
//                continue;
//            }
//            Map<String,Object> param = new HashMap<>();
//            param.put("corpid",corpid);
//            param.put("del",0);
//            param.put("outstockIdIn",allOutstockIds);
//            List<OutstockProductEntity> entitys1 = outstockProductModel.findEntitys(param);
//            Map<Object,Double> outstockPorductMap = new HashMap<>(entitys1.size());
//            List<Long> newTransferIds = new ArrayList<>();
//            for (OutstockProductEntity outstockProductEntity : entitys1) {
//                Long transferId = transferAndOutstock.getOrDefault(outstockProductEntity.getOutWarehouseId(),0L);
//                if (Objects.nonNull(outstockProductEntity.getRefProductId())) {
//                    String key = transferId + "_" + outstockProductEntity.getRefProductId();
//                    newTransferIds.add(transferId);
//                    Double num = outstockPorductMap.getOrDefault(key,0D);
//                    num = Arith.add(outstockProductEntity.getProductNum(),num) ;
//                    outstockPorductMap.put(key,num);
//                }else {
//                    String key = transferId + "_" + outstockProductEntity.getProductId();
//                    Double num = outstockPorductMap.getOrDefault(key,0D);
//                    num = Arith.add(outstockProductEntity.getProductNum(),num) ;
//                    outstockPorductMap.put(key,num);
//                }
//            }
//            param.clear();
//            param.put("corpid",corpid);
//            param.put("del",0);
//            param.put("transferIdIn",allTransferIds);
//            List<TransferProductEntity> entitys = transferProductModel.findEntitys(param);
//            List<TransferProductEntity> updateEntitys = new ArrayList<>(1000);
//            for (TransferProductEntity entity : entitys) {
//                Long contractId = entity.getTransferId();
//                if (newTransferIds.contains(contractId)) {
//                    //新数据逻辑
//                    String key = contractId + "_" + entity.getId();
//                    if (!outstockPorductMap.containsKey(key)) {
//                        entity.setOutstockNum(0D);
//                    }
//                    entity.setOutstockNum(outstockPorductMap.get(key));
//                    outstockPorductMap.remove(key);
//                    updateEntitys.add(entity);
//                    if (updateEntitys.size() >= 1000) {
//                        transferProductModel.updateBatch(updateEntitys, corpid);
//                        updateEntitys = new ArrayList<>(1000);
//                    }
//                    continue;
//                }
//
//                Long productId = entity.getProductId();
//
//
//                String key = contractId + "_" + productId;
//                if (outstockPorductMap.isEmpty() || !outstockPorductMap.containsKey(key)) {
//                    entity.setOutstockNum(0D);
//                    updateEntitys.add(entity);
//                    if (updateEntitys.size() >= 1000) {
//                        transferProductModel.updateBatch(updateEntitys, corpid);
//                        updateEntitys = new ArrayList<>(1000);
//                    }
//                    continue;
//                }
//                Double productNum = entity.getProductNum();
//                Double num = outstockPorductMap.get(key);
//
//                Double outstockNum;
//                if (productNum - num >= 0) {
//                    outstockNum = num;
//                    outstockPorductMap.remove(key);
//                }else {
//                    outstockNum = productNum;
//                    outstockPorductMap.put(key,Arith.sub(num,outstockNum));
//                }
//                entity.setOutstockNum(outstockNum);
//                updateEntitys.add(entity);
//                if (updateEntitys.size() >= 1000) {
//                    transferProductModel.updateBatch(updateEntitys, corpid);
//                    updateEntitys = new ArrayList<>(1000);
//                }
//
//            }
//            if (!updateEntitys.isEmpty()) {
//                transferProductModel.updateBatch(updateEntitys,corpid);
//            }
//
//        }
//        LOG.warn("fixTransferOutStockNum over");
//        return null;
//    }


    /**
     * 刷调拨单入料数量
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixTransferInStockNum", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixTransferInStockNum(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = transferModel.getCorpids();
        }
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fixTransferInStockNum:" + index + "/" + corpidList.size());
            index++;
            long idGte = 0L;
            HashSet<Long> allTransferIds = new HashSet<>();
            Map<Object,Double> instockPorductMap = new HashMap<>();
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                param.put("type", InstockTypeEnum.TRANSFER_INSTOCK.getCode());
                List<InstockProductEntity> entitys = instockProductModel.findEntitys(param);
                if (entitys.isEmpty()){
                    break;
                }
                idGte = entitys.get(entitys.size()-1).getId();
                for (InstockProductEntity entity : entitys) {
                    Long refId = entity.getRefId();
                    allTransferIds.add(refId);
                    String key = refId + "_" + entity.getProductId();
                    Double num = instockPorductMap.getOrDefault(key,0D);
                    num = Arith.add(entity.getProductNum(),num) ;
                    instockPorductMap.put(key,num);
                }
            }
            if (allTransferIds.isEmpty()) {
                continue;
            }

            Map<String,Object> param = new HashMap<>();
            param.clear();
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("transferIdIn",allTransferIds);
            List<TransferProductEntity> entitys = transferProductModel.findEntitys(param);
            List<TransferProductEntity> updateEntitys = new ArrayList<>(1000);
            for (TransferProductEntity entity : entitys) {
                Long contractId = entity.getTransferId();
                Long productId = entity.getProductId();

                String key = contractId + "_" + productId;
                if (instockPorductMap.isEmpty() || !instockPorductMap.containsKey(key)) {
                    entity.setInstockNum(0D);
                    updateEntitys.add(entity);
                    if (updateEntitys.size() >= 1000) {
                        transferProductModel.updateBatch(updateEntitys, corpid);
                        updateEntitys = new ArrayList<>(1000);
                    }
                    continue;
                }
                Double productNum = entity.getProductNum();
                Double num = instockPorductMap.get(key);

                Double instockNum;
                if (productNum - num >= 0) {
                    instockNum = num;
                    instockPorductMap.remove(key);
                }else {
                    instockNum = productNum;
                    instockPorductMap.put(key, Arith.sub(num,instockNum));
                }
                entity.setInstockNum(instockNum);
                updateEntitys.add(entity);
                if (updateEntitys.size() >= 1000) {
                    transferProductModel.updateBatch(updateEntitys, corpid);
                    updateEntitys = new ArrayList<>(1000);
                }
            }
            if (!updateEntitys.isEmpty()) {
                transferProductModel.updateBatch(updateEntitys,corpid);
            }

        }
        LOG.warn("fixTransferInStockNum over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }




    @RequestMapping(value = "/fiXContractShipStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixContractShipStatus(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fixContractShipStatus:" + index + "/" + corpidList.size());
            index++;

            long idGte = 0L;
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                List<ContractEntityExt> entitys = contractModel.findEntitys(param);
                if (entitys.isEmpty()) {
                    break;
                }
                idGte = entitys.get(entitys.size() - 1).getId();
                HashSet<Long> contractIds = new HashSet<>();
                for (ContractEntityExt entity : entitys) {
                    if (Objects.equals(getIntegerOrDefaultFromFormData(entity.getData(), ContractEnum.ALL_OUT_BOUND.getAttr(), AllOutBoundEnum.NON_OUT.getCode()), AllOutBoundEnum.NON_OUT.getCode())) {
                        contractIds.add(entity.getId());
                    }
                }
//                HashSet<Long> outstockContractIds = new HashSet<>();
                List<Long> outstockContractIds = new ArrayList<>();
                if (!contractIds.isEmpty()) {
//                    BoolQueryBuilder boolQueryBuilder = boolQuery();
//                    boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
//                    boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE), OutstockTypeEnum.CONTRACT_OUTSTOCK.getCode()));
//                    boolQueryBuilder.filter(termsQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID), contractIds));
//                    boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
//                    List<PaasFormDataEntityExt> entityExts = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OUTSTOCK, boolQueryBuilder, PaasFormDataEntityExt.class, Arrays.asList("dataId", "data"));
//                    for (PaasFormDataEntityExt entityExt : entityExts) {
//                        outstockContractIds.add(FastJsonHelper.getLongOrDefaultFromFormData(entityExt.getData(), OutstockEnum.REF_ID.getAttr(), 0L));
//                    }
                    param.clear();
                    param.put(StringConstant.CORPID,corpid);
                    param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                    param.put("type",OutstockTypeEnum.CONTRACT_OUTSTOCK.getCode());
                    param.put("refIdIn",contractIds);
                    param.put("columns","DISTINCT ref_id");
                    List<OutstockProductEntity> outstockProductEntityList = outstockProductModel.findEntitys(param);
                    outstockContractIds = outstockProductEntityList.stream().map(OutstockProductEntity::getRefId).collect(Collectors.toList());
                }

                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                for (ContractEntityExt entity : entitys) {
                    Long contractId = entity.getId();
                    JSONObject jsonData = entity.getData();
                    JSONObject data = new JSONObject();
                    String allOutBound = FastJsonHelper.getStringOrDefaultFromFormData(jsonData, ContractEnum.ALL_OUT_BOUND.getAttr(), AllOutBoundEnum.NON_OUT.getCode().toString());
                    if (Objects.equals(allOutBound, AllOutBoundEnum.ALL_OUT.getCode().toString())) {
                        JSONArray formData = FastJsonHelper.getJsonArrOrDefaultFromFormData(jsonData, ContractEnum.PRODUCT.getAttr(), new JSONArray());
                        if (formData.size() < 1) {
                            data.put(ContractEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.UNSHIPPED.getCode());
                        }else {
                            data.put(ContractEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.SHIPPED.getCode());
                        }
                        updateDataEntityList.add(ExplainUtil.getUpdateData(contractId,data,corpid,entity.getUpdateTime()));
                    }else {
                        if (outstockContractIds.contains(contractId)){
                            data.put(ContractEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.DELIVERED.getCode());
                        }else {
                            data.put(ContractEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.UNSHIPPED.getCode());
                        }
                        updateDataEntityList.add(ExplainUtil.getUpdateData(contractId,data,corpid,entity.getUpdateTime()));
                    }
                }
                if (!updateDataEntityList.isEmpty()) {
                    contractModel.updateBatch(updateDataEntityList,corpid,false);
                }
            }

        }
        LOG.warn("fixContractShipStatus over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }



    @RequestMapping(value = "/fiXNoProductContractShipStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fiXNoProductContractShipStatus(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fiXNoProductContractShipStatus:" + index + "/" + corpidList.size());
            index++;

            long idGte = 0L;
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                List<ContractEntityExt> entitys = contractModel.findEntitys(param);
                if (entitys.isEmpty()) {
                    break;
                }
                idGte = entitys.get(entitys.size() - 1).getId();

                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                for (ContractEntityExt entity : entitys) {
                    Long contractId = entity.getId();
                    JSONObject jsonData = entity.getData();
                    JSONObject data = new JSONObject();
                    String allOutBound = FastJsonHelper.getStringOrDefaultFromFormData(jsonData, ContractEnum.ALL_OUT_BOUND.getAttr(), AllOutBoundEnum.NON_OUT.getCode().toString());
                    String shipStatus = FastJsonHelper.getStringOrDefaultFromFormData(jsonData, ContractEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.SHIPPED.getCode());
                    if (Objects.equals(allOutBound, AllOutBoundEnum.ALL_OUT.getCode().toString())) {
                        JSONArray formData = FastJsonHelper.getJsonArrOrDefaultFromFormData(jsonData, ContractEnum.PRODUCT.getAttr(), new JSONArray());
                        if (formData.size() < 1 && !Objects.equals(shipStatus, ShipStatusEnum.UNSHIPPED.getCode())) {
                            data.put(ContractEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.UNSHIPPED.getCode());
                            updateDataEntityList.add(ExplainUtil.getUpdateData(contractId,data,corpid,entity.getUpdateTime()));
                        }
                    }
                }
                if (!updateDataEntityList.isEmpty()) {
                    contractModel.updateBatch(updateDataEntityList,corpid,false);
                }
            }
        }
        LOG.warn("fixContractShipStatus over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }




    @RequestMapping(value = "/fixPurchaseReceieveStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPurchaseReceieveStatus(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = purchaseModel.getCorpidList();
        }
        int index = 1;

        for (String corpid : corpidList) {

            LOG.warn("fixPurchaseReceieveStatus:" + index + "/" + corpidList.size());
            index++;

            long idGte = 0L;
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                List<PurchaseEntityExt> entitys = purchaseModel.findEntitys(param);
                if (entitys.isEmpty()) {
                    break;
                }
                idGte = entitys.get(entitys.size() - 1).getId();

                HashSet<Long> purchaseIds = new HashSet<>();
                for (PurchaseEntityExt entity : entitys) {
                    if (Objects.equals(getIntegerOrDefaultFromFormData(entity.getData(), PurchaseEnum.ALL_INCOMING.getAttr(), AllInBoundEnum.NON_IN.getCode()), AllInBoundEnum.NON_IN.getCode())) {
                        purchaseIds.add(entity.getId());
                    }
                }
                List<Long> instockPurchaeIds = new ArrayList<>();
                if (!purchaseIds.isEmpty()) {
                    param.clear();
                    param.put(StringConstant.CORPID,corpid);
                    param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                    param.put("type",InstockTypeEnum.PURCHASE_INSTOCK.getCode());
                    param.put("refIdIn",purchaseIds);
                    param.put("columns","DISTINCT ref_id");
                    List<InstockProductEntity> instockProductModelEntitys = instockProductModel.findEntitys(param);
                    instockPurchaeIds = instockProductModelEntitys.stream().map(InstockProductEntity::getRefId).collect(Collectors.toList());
                }

                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                for (PurchaseEntityExt entity : entitys) {
                    Long purchaseId = entity.getId();
                    JSONObject jsonData = entity.getData();
                    JSONObject data = new JSONObject();
                    String allIncoming = jsonData.getString(PurchaseEnum.ALL_INCOMING.getAttr());
                    if (Objects.equals(allIncoming, AllInBoundEnum.ALL_IN.getCode().toString())) {
                        data.put(PurchaseEnum.RECEIVE_STATUS.getAttr(), ReceiveStatusEnum.RECEIVED.getCode());
                        updateDataEntityList.add(ExplainUtil.getUpdateData(purchaseId,data,corpid,entity.getUpdateTime()));
                    }else {
                        if (instockPurchaeIds.contains(purchaseId)){
                            data.put(PurchaseEnum.RECEIVE_STATUS.getAttr(), ReceiveStatusEnum.PARTIAL.getCode());
                        }else {
                            data.put(PurchaseEnum.RECEIVE_STATUS.getAttr(), ReceiveStatusEnum.UNRECEIVED.getCode());
                        }
                        updateDataEntityList.add(ExplainUtil.getUpdateData(purchaseId,data,corpid,entity.getUpdateTime()));
                    }
                }
                if (!updateDataEntityList.isEmpty()) {
                    purchaseModel.updateBatch(updateDataEntityList,corpid,false);
                }
            }
        }
        LOG.warn("fixPurchaseReceieveStatus over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }

    @RequestMapping(value = "/fixRefundStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixRefundStatus(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = refundModel.getCorpids();
        }
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fixRefundStatus:" + index + "/" + corpidList.size());
            index++;

            long idGte = 0L;
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                List<RefundEntityExt> entitys = refundModel.findEntitys(param);
                if (entitys.isEmpty()) {
                    break;
                }
                idGte = entitys.get(entitys.size() - 1).getId();
                HashSet<Long> refundIds = new HashSet<>();
                for (RefundEntityExt entity : entitys) {
                    if (Objects.equals(getIntegerOrDefaultFromFormData(entity.getData(), RefundEnum.ALL_IN_BOUND.getAttr(), AllInBoundEnum.NON_IN.getCode()), AllInBoundEnum.NON_IN.getCode())) {
                        refundIds.add(entity.getId());
                    }
                }
                List<Long> instockRefundIds = new ArrayList<>();
                if (!refundIds.isEmpty()) {
                    param.clear();
                    param.put(StringConstant.CORPID,corpid);
                    param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                    param.put("type",InstockTypeEnum.RED_CONTRACT_INSTOCK.getCode());
                    param.put("refIdIn",refundIds);
                    param.put("columns","DISTINCT ref_id");
                    List<InstockProductEntity> instockProductModelEntitys = instockProductModel.findEntitys(param);
                    instockRefundIds = instockProductModelEntitys.stream().map(InstockProductEntity::getRefId).collect(Collectors.toList());
                }

                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                for (RefundEntityExt entity : entitys) {
                    Long refundId = entity.getId();
                    JSONObject jsonData = entity.getData();
                    JSONObject data = new JSONObject();
                    String allIncoming = jsonData.getString(RefundEnum.ALL_IN_BOUND.getAttr());
                    if (Objects.equals(allIncoming, AllInBoundEnum.ALL_IN.getCode().toString())) {
                        JSONArray formData = FastJsonHelper.getJsonArrOrDefaultFromFormData(jsonData, RefundEnum.PRODUCTS.getAttr(), new JSONArray());
                        if (formData.size() < 1) {
                            data.put(RefundEnum.REFUND_STATUS.getAttr(), RefundStatusEnum.UNREFUND.getCode());
                        } else {
                            data.put(RefundEnum.REFUND_STATUS.getAttr(), RefundStatusEnum.REFUND.getCode());
                        }
                        updateDataEntityList.add(ExplainUtil.getUpdateData(refundId, data, corpid, entity.getUpdateTime()));
                    } else {
                        if (instockRefundIds.contains(refundId)) {
                            data.put(RefundEnum.REFUND_STATUS.getAttr(), RefundStatusEnum.PARTIAL.getCode());
                        } else {
                            data.put(RefundEnum.REFUND_STATUS.getAttr(), RefundStatusEnum.UNREFUND.getCode());
                        }
                        updateDataEntityList.add(ExplainUtil.getUpdateData(refundId, data, corpid, entity.getUpdateTime()));
                    }
                }
                if (!updateDataEntityList.isEmpty()) {
                    refundModel.updateBatch(updateDataEntityList, corpid, false);
                }
            }
        }
        LOG.warn("fixRefundStatus over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }

    @RequestMapping(value = "/fixReturnedPurchaseStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixReturnedPurchaseStatus(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = returnedPurchaseModel.getCorpids();
        int index = 1;
        for (String corpid : corpidList) {
            LOG.warn("fixReturnedPurchaseStatus:" + index + "/" + corpidList.size());
            index++;

            long idGte = 0L;
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                List<ReturnedPurchaseEntityExt> entitys = returnedPurchaseModel.findEntitys(param);
                if (entitys.isEmpty()) {
                    break;
                }
                idGte = entitys.get(entitys.size() - 1).getId();

                HashSet<Long> returnPurchaeIds = new HashSet<>();
                for (ReturnedPurchaseEntityExt entity : entitys) {
                    if (getIntegerOrDefaultFromFormData(entity.getData(), ReturnedPurchaseEnum.OUTSTOCK_ID.getAttr(), 0) <= 0) {
                        returnPurchaeIds.add(entity.getId());
                    }
                }
                List<Long> outstockContractIds = new ArrayList<>();
                if (!returnPurchaeIds.isEmpty()) {
                    param.clear();
                    param.put(StringConstant.CORPID,corpid);
                    param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                    param.put("type",OutstockTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode());
                    param.put("refIdIn",returnPurchaeIds);
                    param.put("columns","DISTINCT ref_id");
                    List<OutstockProductEntity> outstockProductEntities = outstockProductModel.findEntitys(param);
                    outstockContractIds = outstockProductEntities.stream().map(OutstockProductEntity::getRefId).collect(Collectors.toList());
                }

                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                for (ReturnedPurchaseEntityExt entity : entitys) {
                    Long returnedPurchaseId = entity.getId();
                    JSONObject jsonData = entity.getData();
                    JSONObject data = new JSONObject();
                    Integer outstockId = getIntegerOrDefaultFromFormData(jsonData, ReturnedPurchaseEnum.OUTSTOCK_ID.getAttr(), 0);
                    if (outstockId > 0) {
                        data.put(ReturnedPurchaseEnum.RETURNED_STATUS.getAttr(), ReturnedStatusEnum.RETURNED.getCode());
                        updateDataEntityList.add(ExplainUtil.getUpdateData(returnedPurchaseId,data,corpid,entity.getUpdateTime()));
                    }else {
                        if (outstockContractIds.contains(returnedPurchaseId)){
                            data.put(ReturnedPurchaseEnum.RETURNED_STATUS.getAttr(), ReturnedStatusEnum.DELIVERED.getCode());
                        }else {
                            data.put(ReturnedPurchaseEnum.RETURNED_STATUS.getAttr(), ReturnedStatusEnum.UNRETURNED.getCode());
                        }
                        updateDataEntityList.add(ExplainUtil.getUpdateData(returnedPurchaseId,data,corpid,entity.getUpdateTime()));
                    }
                }
                if (!updateDataEntityList.isEmpty()) {
                    returnedPurchaseModel.updateBatch(updateDataEntityList,corpid,false);
                }
            }

        }
        LOG.warn("fixReturnedPurchaseStatus over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }

    @RequestMapping(value = "/fixTransferStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixTransferStatus(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = transferModel.getCorpids();
        int index = 1;
        for (String corpid : corpidList) {
            LOG.warn("fixTransferStatus:" + index + "/" + corpidList.size());
            index++;

            long idGte = 0L;
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                List<TransferEntityExt> entitys = transferModel.findEntitys(param);
                if (entitys.isEmpty()) {
                    break;
                }
                idGte = entitys.get(entitys.size() - 1).getId();

                HashSet<Long> transferIds = new HashSet<>();
                for (TransferEntityExt entity : entitys) {
                    Integer allInBound = entity.getData().getInteger(TransferEnum.ALL_IN_BOUND.getAttr());
                    if (Objects.nonNull(allInBound) && !Objects.equals(allInBound,AllInBoundEnum.ALL_IN.getCode())) {
                        transferIds.add(entity.getId());
                    }
                }

                List<Long> outstockTransferIds = new ArrayList<>();
                List<Long> instockTransferIds = new ArrayList<>();
                if (!transferIds.isEmpty()) {
                    param.clear();
                    param.put(StringConstant.CORPID,corpid);
                    param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                    param.put("type",OutstockTypeEnum.TRANSFER_OUTSTOCK.getCode());
                    param.put("refIdIn",transferIds);
                    param.put("columns","DISTINCT ref_id");
                    List<OutstockProductEntity> outstockProductEntities = outstockProductModel.findEntitys(param);
                    outstockTransferIds = outstockProductEntities.stream().map(OutstockProductEntity::getRefId).collect(Collectors.toList());
                    param.clear();
                    param.put(StringConstant.CORPID,corpid);
                    param.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
                    param.put("type",InstockTypeEnum.TRANSFER_INSTOCK.getCode());
                    param.put("refIdIn",transferIds);
                    param.put("columns","DISTINCT ref_id");
                    List<InstockProductEntity> instockProductEntityList = instockProductModel.findEntitys(param);
                    instockTransferIds = instockProductEntityList.stream().map(InstockProductEntity::getRefId).collect(Collectors.toList());
                }

                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                for (TransferEntityExt entity : entitys) {
                    Long transferId = entity.getDataId();
                    JSONObject jsonData = entity.getData();
                    JSONObject data = new JSONObject();
                    Integer allInBound = jsonData.getInteger(TransferEnum.ALL_IN_BOUND.getAttr());
                    if (Objects.isNull(allInBound)) {
                        Integer outstockId = jsonData.getInteger(TransferEnum.OUTSTOCK_ID.getAttr());
                        Integer instockId = jsonData.getInteger(TransferEnum.INSTOCK_ID.getAttr());
                        if (Objects.isNull(outstockId) || outstockId < 1) {
                            data.put(TransferEnum.TRANSFER_STATUS.getAttr(), TransferNewStatusEnum.UNTRANSFORMED.getCode());
                        }else if (Objects.isNull(instockId) || instockId < 1){
                            data.put(TransferEnum.TRANSFER_STATUS.getAttr(), TransferNewStatusEnum.UNRECEIVED.getCode());
                        }else {
                            data.put(TransferEnum.TRANSFER_STATUS.getAttr(), TransferNewStatusEnum.TRANSFERRED.getCode());
                        }
                        updateDataEntityList.add(ExplainUtil.getUpdateData(transferId,data,corpid,entity.getUpdateTime()));
                        continue;
                    }
                    if (Objects.equals(allInBound,AllInBoundEnum.ALL_IN.getCode())) {
                        data.put(TransferEnum.TRANSFER_STATUS.getAttr(), TransferNewStatusEnum.TRANSFERRED.getCode());
                        updateDataEntityList.add(ExplainUtil.getUpdateData(transferId,data,corpid,entity.getUpdateTime()));
                    }else {
                        if (!outstockTransferIds.contains(transferId)) {
                            data.put(TransferEnum.TRANSFER_STATUS.getAttr(), TransferNewStatusEnum.UNTRANSFORMED.getCode());
                            updateDataEntityList.add(ExplainUtil.getUpdateData(transferId,data,corpid,entity.getUpdateTime()));
                        }else {
                            if (instockTransferIds.contains(transferId)) {
                                data.put(TransferEnum.TRANSFER_STATUS.getAttr(), TransferNewStatusEnum.DELIVERED.getCode());
                            }else {
                                data.put(TransferEnum.TRANSFER_STATUS.getAttr(), TransferNewStatusEnum.UNRECEIVED.getCode());
                            }
                            updateDataEntityList.add(ExplainUtil.getUpdateData(transferId,data,corpid,entity.getUpdateTime()));
                        }
                    }
                }
                if (!updateDataEntityList.isEmpty()) {
                    transferDao.updateBatch(updateDataEntityList, corpid);
                   // transferModel.updateBatch(updateDataEntityList,corpid,false);
                }
            }

        }
        LOG.warn("fixTransferStatus over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }

    @RequestMapping(value = "/fixInventoryStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixInventoryStatus(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = inventoryModel.getCorpids();
        int index = 1;
        for (String corpid : corpidList) {
            LOG.warn("fixInventoryStatus:" + index + "/" + corpidList.size());
            index++;

            long idGte = 0L;
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                List<InventoryEntityExt> entitys = inventoryModel.findEntitys(param);
                if (entitys.isEmpty()) {
                    break;
                }
                idGte = entitys.get(entitys.size() - 1).getId();
                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                for (InventoryEntityExt entity : entitys) {
                    Long inventoryId = entity.getDataId();
                    JSONObject jsonData = entity.getData();
                    Integer isProfit = getIntegerOrDefaultFromFormData(jsonData, InventoryEnum.IF_PROFIT.getAttr(), 0);
                    Integer isLoss = getIntegerOrDefaultFromFormData(jsonData, InventoryEnum.IF_LOSS.getAttr(), 0);
                    Integer instockId = getIntegerOrDefaultFromFormData(jsonData, InventoryEnum.INSTOCK_ID.getAttr(), 0);
                    Integer outstockId = getIntegerOrDefaultFromFormData(jsonData, InventoryEnum.OUTSTOCK_ID.getAttr(), 0);
                    JSONObject data = new JSONObject();
                    data.put(InventoryEnum.INVENTORY_STATUS.getAttr(), InventoryNewStatusEnum.UNFINISHED.getCode());
                    if (Objects.equals(isLoss,0) && Objects.equals(isProfit,0)) {
                        data.put(InventoryEnum.INVENTORY_STATUS.getAttr(), InventoryNewStatusEnum.FINISHED.getCode());
                    }else if (Objects.equals(isLoss,0) && Objects.equals(isProfit,1)){
                        if (!Objects.equals(instockId,0)) {
                            data.put(InventoryEnum.INVENTORY_STATUS.getAttr(), InventoryNewStatusEnum.FINISHED.getCode());
                        }
                    }else if(Objects.equals(isLoss,1) && Objects.equals(isProfit,0)){
                        if (!Objects.equals(outstockId,0)) {
                            data.put(InventoryEnum.INVENTORY_STATUS.getAttr(), InventoryNewStatusEnum.FINISHED.getCode());
                        }
                    }else {
                        if (!Objects.equals(outstockId,0) && !Objects.equals(instockId,0)) {
                            data.put(InventoryEnum.INVENTORY_STATUS.getAttr(), InventoryNewStatusEnum.FINISHED.getCode());
                        }
                    }
                    updateDataEntityList.add(ExplainUtil.getUpdateData(inventoryId,data,corpid,entity.getUpdateTime()));
                }
                if (!updateDataEntityList.isEmpty()) {
                    inventoryDao.updateBatch(updateDataEntityList, corpid);
                    //inventoryModel.updateBatch(updateDataEntityList,corpid,false);
                }
            }

            }

        LOG.warn("fixInventoryStatus over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }




    /**
     * 刷数据销售退货入库单价
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/fixRefundInstockPrice", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixRefundInstockPrice(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = refundModel.getCorpids();
        int index = 1;

        for (String corpid : corpidList) {
            LOG.warn("fixRefundInstockPrice:" + index + "/" + corpidList.size());
            index++;
            long idGte = 0L;
            HashSet<Long> allRefundIds = new HashSet<>();
            List<Long> allInstockIds = new ArrayList<>();
            Map<Long,Long> refundAndInstock = new HashMap<>();
            while (true) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idGte", idGte);
                param.put("orderByStr", "id asc");
                param.put("pageSize", 1000);
                param.put("type", InstockTypeEnum.RED_CONTRACT_INSTOCK.getCode());
                List<InstockProductEntity> entitys = instockProductModel.findEntitys(param);
                if (entitys.isEmpty()) {
                    break;
                }
                idGte = entitys.get(entitys.size() - 1).getId();
                for (InstockProductEntity entity : entitys) {
                    allRefundIds.add(entity.getRefId());
                    allInstockIds.add(entity.getIntoWarehouseId());
                    refundAndInstock.put(entity.getIntoWarehouseId(),entity.getRefId());
                }
            }
            if (allRefundIds.isEmpty()) {
                continue;
            }

            Map<String,Object> param = new HashMap<>();
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("idIn",allRefundIds);
            List<RefundEntityExt> entitys = refundModel.findEntitys(param);
            HashSet<Long> redConbtractIds = new HashSet<>();
            for (RefundEntityExt entity : entitys) {
                redConbtractIds.add(entity.getData().getLong(RefundEnum.RED_CONTRACT_ID.getAttr()));
            }
            param.clear();
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("contractIdIn", redConbtractIds);
            List<ContractProductEntity> redContractEntitys = contractProductModel.findEntitys(param);

            Map<Long, Double> refProductMap = new HashMap<>();
            for (ContractProductEntity redContractEntity : redContractEntitys) {
                refProductMap.put(redContractEntity.getId(), redContractEntity.getPrice());
            }


            param.clear();
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("instockIdIn",allInstockIds);
            List<InstockProductEntity> entitys1 = instockProductModel.findEntitys(param);
            List<InstockProductEntity> updateEntitys = new ArrayList<>(1000);
            for (InstockProductEntity instockProductEntity : entitys1) {

                if (Objects.nonNull(instockProductEntity.getRefProductId())) {
                    Double price = refProductMap.getOrDefault(instockProductEntity.getRefProductId(), 0D);
                    instockProductEntity.setPrice(price);
                    JSONObject data = instockProductEntity.getData();
                    if (Objects.nonNull(data)) {
                        data.put(SelectProductEnum.PRICE.getAttr(), price);
                    }
                    updateEntitys.add(instockProductEntity);
                    if (updateEntitys.size() >= 1000) {
                        instockProductModel.updateBatch(updateEntitys, corpid);
                        updateEntitys = new ArrayList<>(1000);
                    }
                }
            }
            if (!updateEntitys.isEmpty()) {
                instockProductModel.updateBatch(updateEntitys, corpid);
            }

        }
        LOG.warn("fixRefundInstockPrice over");
        LOG.warn("consume" + (DateTimeUtil.getInt() - start));
        return null;
    }



}
